package cn.com.anysdk.sms.monitor;

import cn.com.anysdk.sms.exception.SmsException;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;

/**
 * SMS监控管理器，提供异常监控和指标统计
 */
@Slf4j
public class SmsMonitorManager {
    private static final SmsMonitorManager INSTANCE = new SmsMonitorManager();

    private final List<SmsExceptionListener> exceptionListeners = new CopyOnWriteArrayList<>();
    private final Map<String, AtomicLong> operationCounters = new ConcurrentHashMap<>();
    private final Map<String, AtomicLong> errorCounters = new ConcurrentHashMap<>();
    private final Map<String, AtomicLong> durationTotals = new ConcurrentHashMap<>();

    private SmsMonitorManager() {}

    public static SmsMonitorManager getInstance() {
        return INSTANCE;
    }

    /**
     * 添加异常监听器
     */
    public void addExceptionListener(SmsExceptionListener listener) {
        exceptionListeners.add(listener);
    }

    /**
     * 移除异常监听器
     */
    public void removeExceptionListener(SmsExceptionListener listener) {
        exceptionListeners.remove(listener);
    }

    /**
     * 记录操作
     */
    public void recordOperation(SmsOperationContext context) {
        String key = getKey(context.getProvider(), context.getOperationType());
        operationCounters.computeIfAbsent(key, k -> new AtomicLong()).incrementAndGet();
        durationTotals.computeIfAbsent(key, k -> new AtomicLong()).addAndGet(context.getDuration());

        if (!context.isSuccess()) {
            errorCounters.computeIfAbsent(key, k -> new AtomicLong()).incrementAndGet();
        }

        log.info("SMS operation recorded: provider={}, type={}, duration={}ms, success={}", 
            context.getProvider(), context.getOperationType(), context.getDuration(), context.isSuccess());
    }

    /**
     * 处理异常
     */
    public void handleException(SmsException exception, SmsOperationContext context) {
        for (SmsExceptionListener listener : exceptionListeners) {
            try {
                listener.onException(exception, context);
            } catch (Exception e) {
                log.error("Error notifying exception listener", e);
            }
        }
    }

    /**
     * 获取操作计数
     */
    public long getOperationCount(String provider, String operationType) {
        return operationCounters.getOrDefault(getKey(provider, operationType), new AtomicLong()).get();
    }

    /**
     * 获取错误计数
     */
    public long getErrorCount(String provider, String operationType) {
        return errorCounters.getOrDefault(getKey(provider, operationType), new AtomicLong()).get();
    }

    /**
     * 获取平均操作时间
     */
    public double getAverageOperationTime(String provider, String operationType) {
        String key = getKey(provider, operationType);
        long totalDuration = durationTotals.getOrDefault(key, new AtomicLong()).get();
        long totalOperations = operationCounters.getOrDefault(key, new AtomicLong()).get();
        return totalOperations > 0 ? (double) totalDuration / totalOperations : 0;
    }

    /**
     * 重置统计数据
     */
    public void resetStatistics() {
        operationCounters.clear();
        errorCounters.clear();
        durationTotals.clear();
    }

    private String getKey(String provider, String operationType) {
        return provider + ":" + operationType;
    }

    /**
     * 异常监听器接口
     */
    public interface SmsExceptionListener {
        void onException(SmsException exception, SmsOperationContext context);
    }
} 